home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / wstype / source / getfiles.c < prev    next >
C/C++ Source or Header  |  1991-10-18  |  8KB  |  319 lines

  1. /***   [getfiles.c]
  2. *
  3. *    ディレクトリ情報 関連        (C)ささがわ
  4. *
  5. *    For GNU C Compiler (GCC)   Version 1.39
  6. *
  7. ***/
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <dos.h>
  13. #include "jstring.h"
  14. #include "getfiles.h"
  15.  
  16. #define DEFAULT_BUF    30
  17. #define ADD_BUF        50
  18.  
  19. #define STBUF_RETRY    -1
  20. #define STBUF_FATAL    -2
  21.  
  22. typedef unsigned char    Uchar;
  23.  
  24. static files *buf = NULL;
  25.  
  26. static int    Set_buf(unsigned *);
  27. static int    Set_buf_again(int);
  28. static void Sort_ext(files **, unsigned);
  29. static void Sort_date(files **, unsigned);
  30. static void Sort_name(files **, unsigned);
  31. static void Sort_non(files **, unsigned);
  32. static int cmp_dirornot(files **, files **);
  33. static int cmp_base(files **, files **);
  34. static int cmp_ext(files **, files **);
  35. static int cmp_date(files **, files **);
  36. static int cmp_name(files **, files **);
  37. static int cmp_non(files **, files **);
  38. static Uchar *get_extptr(Uchar *);
  39.  
  40. int Getfiles(int type, get_f *gf, int mode) {
  41.     int            n;
  42.     unsigned    n_file;
  43.     unsigned    n_dir;
  44.     unsigned    mf = DEFAULT_BUF;
  45.     files        **ptr;
  46.     
  47.     if (mode == 0) {
  48.         while ((n = Set_buf(&mf)) == STBUF_RETRY)
  49.             mf += ADD_BUF;
  50.         if (n == STBUF_FATAL) {
  51.             gf->pbuf = NULL;
  52.             return 1;
  53.         }
  54.         ptr = (files **)(buf + mf);
  55.         n_file = n;
  56.         n_dir = 0;
  57.         
  58.         for (n = 0;n < mf;n++)
  59.             ptr[n] = buf + n;
  60.     } else {
  61.         ptr = gf->pbuf;
  62.         n_file = gf->nfiles;
  63.         n_dir = gf->ndir;
  64.     }
  65.     if (n_file == 0) {
  66.         gf->pbuf = ptr;
  67.         gf->nfiles = n_file;
  68.         gf->ndir = n_dir;
  69.         return 0;
  70.     }
  71.     
  72.     /* ディレクトリ分離 */
  73.     qsort((void *)ptr, (size_t)n_file, (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_dirornot);
  74.     
  75.     n = 0;
  76.     while (ptr[n]->attr & _A_SUBDIR && n < n_file)
  77.         n++;
  78.     n_dir = n;
  79.     
  80.     switch (type) {
  81.         case GF_SEXT:
  82.             Sort_name(ptr, n_dir);
  83.             Sort_ext(ptr + n_dir, n_file - n_dir);
  84.             break;
  85.         
  86.         case GF_SDATE:
  87.             Sort_date(ptr, n_dir);
  88.             Sort_date(ptr + n_dir, n_file - n_dir);
  89.             break;
  90.         
  91.         case GF_SNAME:
  92.             Sort_name(ptr, n_dir);
  93.             Sort_name(ptr + n_dir, n_file - n_dir);
  94.             break;
  95.         
  96.         default:
  97.             Sort_non(ptr, n_dir);
  98.             Sort_non(ptr + n_dir, n_file - n_dir);
  99.             break;
  100.     }
  101.     
  102.     gf->pbuf = ptr;
  103.     gf->nfiles = n_file;
  104.     gf->ndir = n_dir;
  105.     return 0;
  106. }
  107.  
  108. static int Set_buf(unsigned *cap_buf) {
  109.     int            n_file;
  110.     unsigned    atr = _A_NORMAL | _A_RDONLY | _A_SUBDIR | _A_ARCH;
  111.     struct find_t    ft;
  112.     
  113.     Gf_bufrel();
  114.     if ((buf = (files *)malloc(*cap_buf * (sizeof(files) + sizeof(files *)))) == NULL)
  115.         return STBUF_FATAL;
  116.     
  117.     n_file = 0;
  118.     if (!_dos_findfirst("*.*", atr, &ft)) {
  119.         if (strcmp(".", ft.name) || !(ft.attrib & _A_SUBDIR)) {
  120.             strcpy((char *)buf[n_file].name, (const char *)ft.name);
  121.             buf[n_file].attr = ft.attrib;
  122.             buf[n_file].dt = ft.wr_date;
  123.             buf[n_file].tm = ft.wr_time;
  124.             buf[n_file].ord = n_file;
  125.             buf[n_file++].sz = ft.size;
  126.         }
  127.         if (n_file >= *cap_buf) {
  128.             if (Set_buf_again(*cap_buf))
  129.                 return STBUF_RETRY;
  130.             *cap_buf += ADD_BUF;
  131.         }
  132.         
  133.         while (!_dos_findnext(&ft)) {
  134.             if (strcmp(".", ft.name) || !(ft.attrib & _A_SUBDIR)) {
  135.                 strcpy((char *)buf[n_file].name, (const char *)ft.name);
  136.                 buf[n_file].attr = ft.attrib;
  137.                 buf[n_file].dt = ft.wr_date;
  138.                 buf[n_file].tm = ft.wr_time;
  139.                 buf[n_file].ord = n_file;
  140.                 buf[n_file++].sz = ft.size;
  141.             }
  142.             if (n_file >= *cap_buf) {
  143.                 if (Set_buf_again(*cap_buf))
  144.                     return STBUF_RETRY;
  145.                 *cap_buf += ADD_BUF;
  146.             }
  147.         }
  148.     }
  149.     
  150.     return n_file;
  151. }
  152.  
  153. static int Set_buf_again(int n) {
  154.     files    *buf2;
  155.     
  156.     if ((buf2 = (files *)malloc((n + ADD_BUF) * (sizeof(files) + sizeof(files *)))) == NULL)
  157.         return -1;
  158.     memcpy(buf2, buf, n * (sizeof(files) + sizeof(files *)));
  159.     free(buf);
  160.     buf = buf2;
  161.     
  162.     return 0;
  163. }
  164.  
  165. /*   拡張子でソートし、そのうえでベース名でソートする関数   */
  166. static void Sort_ext(files **ptr, unsigned no) {
  167.     int    n = 0;
  168.     
  169.     qsort((void *)ptr, (size_t)no, (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_ext);
  170.     
  171.     while (n < no) {
  172.         Uchar    *startptr;
  173.         unsigned        start;
  174.         
  175.         start = n;
  176.         startptr = get_extptr((Uchar *)ptr[n++]->name);
  177.         while (!strcmp((const char *)startptr, (const char *)get_extptr((Uchar *)(ptr[n]->name))) && n < no)
  178.             n++;
  179.         qsort((void *)(ptr + start), (size_t)(n - start), (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_base);
  180.     }
  181. }
  182.  
  183. /*   作成日時でソートする関数   */
  184. static void Sort_date(files **ptr, unsigned no) {
  185.     int        n = 0;
  186.     
  187.     qsort((void *)ptr, (size_t)no, (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_date);
  188.     
  189.     while (n < no) {
  190.         int        t, d, st;
  191.         
  192.         st = n;
  193.         d = ptr[n]->dt;    t = ptr[n++]->tm;
  194.         while (d == ptr[n]->dt && t == ptr[n]->tm && n < no)
  195.             n++;
  196.         qsort((void *)(ptr + st), (size_t)(n - st), (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_name);
  197.     }
  198. }
  199.  
  200. /*   ファイル名全体でソートする関数   */
  201. static void Sort_name(files **ptr, unsigned no) {
  202.     qsort((void *)ptr, (size_t)no, (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_name);
  203. }
  204.  
  205. /*   ディレクトリ順にソートする関数   */
  206. static void Sort_non(files **ptr, unsigned no) {
  207.     qsort((void *)ptr, (size_t)no, (size_t)sizeof(files *), (int (*)(const void *, const void *))cmp_non);
  208. }
  209.  
  210. /*   qsort関数用、サブディレクトリを識別する関数   */
  211. static int cmp_dirornot(files **a, files **b) {
  212.     if ((*a)->attr & _A_SUBDIR && (*b)->attr & _A_SUBDIR)
  213.         return 0;
  214.     else if ((*a)->attr & _A_SUBDIR)
  215.         return -1;
  216.     else if ((*b)->attr & _A_SUBDIR)
  217.         return 1;
  218.     else
  219.         return 0;
  220. }
  221.  
  222. /*   qsort関数用、ベース名を比較する関数   */
  223. static int cmp_base(files **a, files **b) {
  224.     Uchar c[13], d[13], *e;
  225.     
  226.     strcpy((char *)c, (const char *)(*a)->name);
  227.     if ((e = jstrchr(c, '.')) != NULL)
  228.         *e = '\0';
  229.     strcpy((char *)d, (const char *)(*b)->name);
  230.     if ((e = jstrchr(d, '.')) != NULL)
  231.         *e = '\0';
  232.     return jstrcmp(c, d);
  233. }
  234.  
  235. /*   qsort関数用、拡張子を比較する関数   */
  236. static int cmp_ext(files **a, files **b) {
  237.     return jstrcmp(get_extptr((Uchar *)(*a)->name), get_extptr((Uchar *)(*b)->name));
  238. }
  239.  
  240. /*   qsort関数用、作成日時を比較する関数   */
  241. static int cmp_date(files **a, files **b) {
  242.     unsigned long    d1, d2;
  243.     
  244.     d1 = ((*a)->dt << 16) + (*a)->tm;
  245.     d2 = ((*b)->dt << 16) + (*b)->tm;
  246.     if (d1 > d2)
  247.         return 1;
  248.     else if (d1 < d2)
  249.         return -1;
  250.     else
  251.         return 0;
  252. }
  253.  
  254. /*   qsort関数用、ファイル名全体を比較する関数   */
  255. static int cmp_name(files **a, files **b) {
  256.     if ((*a)->name[0] == '.' || (*b)->name[0] == '.')
  257.         return jstrcmp((Uchar *)(*a)->name, (Uchar *)(*b)->name);
  258.     else
  259.         return jstrcmp((Uchar *)(*a)->name, (Uchar *)(*b)->name);
  260. }
  261.  
  262. /*   qsort関数用、ディレクトリ順を比較する関数   */
  263. static int cmp_non(files **a, files **b) {
  264.     if ((*a)->ord > (*b)->ord)
  265.         return 1;
  266.     else if ((*a)->ord < (*b)->ord)
  267.         return -1;
  268.     else
  269.         return 0;
  270. }
  271.  
  272. /*   拡張子へのポインタを返す関数   */
  273. static Uchar *get_extptr(Uchar *a) {
  274.     Uchar *b;
  275.  
  276.     if ((b = jstrchr(a, '.')) == NULL)
  277.         return (a + strlen((char *)a));
  278.     else
  279.         return (b + 1);
  280. }
  281.  
  282. void Gf_bufrel(void) {
  283.     free(buf);
  284.     buf = NULL;
  285. }
  286.  
  287. int Split_fname(const char *f_name, unsigned atr, char *buf_base, char *buf_ext) {
  288.     int        ret;
  289.     char    *a;
  290.     static const char    *exec_ext[] = {
  291.         ".COM", ".EXE", ".EXP", ".BAT", ""
  292.     };
  293.     
  294.     if ((a = strchr(f_name, '.')) == NULL) {
  295.         strcpy(buf_base, f_name);
  296.         buf_ext[0] = '\0';
  297.     } else {
  298.         buf_base[0] = '\0';
  299.         strncat(buf_base, f_name, a - f_name);
  300.         strcpy(buf_ext, a);
  301.     }
  302.     
  303.     if (atr & _A_SUBDIR) {
  304.         ret = EX_DIR;
  305.     } else {
  306.         int        i;
  307.         
  308.         ret = EX_OTHER;
  309.         for (i = 0; exec_ext[i][0]; i++) {
  310.             if (!stricmp(buf_ext, exec_ext[i])) {
  311.                 ret = EX_EXE;
  312.                 break;
  313.             }
  314.         }
  315.     }
  316.     
  317.     return ret;
  318. }
  319.